'use strict';
const BaseService = require('./base');

const StringUtil = require('../utils/StringUtil');
const ResponseUtil = require('../utils/ResponseUtil');

class UserService extends BaseService {


    async getRealNameAuthStatus(userId) {

        let sql = 'select status from t_user_auth_audit where valid=1 and user_id=? and type=0';
        let list = await this.executeSql(sql, [userId]);

        if (list.length === 0) {
            return -1;//未认证
        } else {
            let statusArr = [];
            for (let i = 0; i < list.length; i++) {
                if (!statusArr.includes(list[i].status)) {
                    statusArr.push(list[i].status)
                }
            }

            if (statusArr.includes(1)) {
                return 1;//已认证
            }

            if (statusArr.includes(0)) {
                return 0;//待审核
            }

            if (statusArr.includes(2)) {
                return 2;//审核未通过
            }
        }

        return -1;
    }

    async getBreedAuthStatus(userId) {
        let sql = 'select status from t_user_auth_audit where valid=1 and user_id=? and type=1';
        let list = await this.executeSql(sql, [userId]);
        if (list.length === 0) {
            return -1;//未认证
        } else {
            let statusArr = [];
            for (let i = 0; i < list.length; i++) {
                if (!statusArr.includes(list[i].status)) {
                    statusArr.push(list[i].status)
                }
            }

            if (statusArr.includes(1)) {
                return 1;//已认证
            }

            if (statusArr.includes(0)) {
                return 0;//待审核
            }

            if (statusArr.includes(2)) {
                return 2;//审核未通过
            }
        }

        return -1;
    }

    async getUserMargin(userId) {
        let sql = 'select amount,frozen,remark from t_user_margin where user_id=? ';
        let margin = await this.executeSqlFirst(sql, [userId]);
        return margin
    }

    async getUserList({keyword, pageNum, pageSize}) {

        let sql = 'select SQL_CALC_FOUND_ROWS * from t_user where 1=1  ';

        let options = [];
        if (keyword) {
            sql += ` and (phone=? or email=? or name=? or user_no=?) `;
            options.push(keyword);
            options.push(keyword);
            options.push(keyword);
            options.push(keyword);
        }

        sql += " order by create_time desc ";

        sql = this.addMysqlPageSize(sql, pageNum, pageSize);
        let result = await this.queryPageData(sql, options);

        let list = result.list;

        await Promise.all(list.map(async (item) => {
            item.realNameAuthStatus = await this.getRealNameAuthStatus(item.id);
            item.breedAuthStatus = await this.getBreedAuthStatus(item.id);
            item.userMargin = await this.getUserMargin(item.id);
        }));

        return result;
    }

    async getUserDetail() {
        let id = this.ctx.params.id;
        let sql = 'select SQL_CALC_FOUND_ROWS * from t_user where id=?  ';
        let object = await this.executeSqlFirst(sql, [id]);
        if (object) {
            object.realNameAuthStatus = await this.getRealNameAuthStatus(object.id);
            object.breedAuthStatus = await this.getBreedAuthStatus(object.id);


            let sql = 'select amount,frozen,remark from t_user_margin where user_id=? ';
            let margin = await this.executeSqlFirst(sql, [id]);

            sql = 'select * from t_user_margin_record where user_id=? order by create_time desc ';
            let marginRecord = await this.executeSql(sql, [id]);

            object.userMargin = margin;
            object.userMarginRecord = marginRecord;
        }
        return object;
    }


    async userAuditSwitch() {
        let {userId, auditSwitch} = this.ctx.request.body;
        if (!userId || ![0, 1].includes(auditSwitch)) {
            return ResponseUtil.retArgErr();
        }

        let sql = 'update t_user set audit_switch=? where id=? ';
        let size = await this.executeSqlSucc(sql, [auditSwitch, userId]);
        return size;
    }


    async updateUserStatus() {
        let {action, userId, status} = this.ctx.request.body;
        if (!userId || !['status', 'prohibitPublish', 'prohibitTrade'].includes(action) || ![0, 1].includes(status)) {
            return ResponseUtil.retArgErr();
        }

        const actionMap = {
            status: 'status',
            prohibitPublish: 'prohibit_publish',
            prohibitTrade: 'prohibit_trade'
        };

        let sql = `update t_user set ${actionMap[action]}=? where id=?`;
        let size = await this.executeSqlSucc(sql, [status, userId]);
        return size;
    }


    async getUserAuthAuditList({type, status, phone, pageNum, pageSize}) {

        let sql = 'select SQL_CALC_FOUND_ROWS a.*,b.user_no,b.name as user_name from t_user_auth_audit a inner join t_user b on a.user_id=b.id where 1=1 ';

        let wheres = [
            {column: 'status', value: status, options: {tname: 'a'}},
            {column: 'type', value: type, options: {tname: 'a'}},
            {column: 'phone', value: phone, options: {tname: 'a', condition: 'like'}}
        ];

        let formatSqlResult = this.formatSqlWhere(sql, wheres);

        sql = formatSqlResult[0];

        sql += " order by a.status asc,a.create_time desc ";

        let options = formatSqlResult[1];

        sql = this.addMysqlPageSize(sql, pageNum, pageSize);
        let result = await this.queryPageData(sql, options);

        let list = result.list;
        await Promise.all(list.map(async (item) => {
            try {
                item.breedCerts = JSON.parse(item.breedCerts);
            } catch (e) {
                item.breedCerts = []
            }
        }));
        return result;
    }

    async getUserAuthAuditDetail() {
        let id = this.ctx.params.id;
        let sql = 'select SQL_CALC_FOUND_ROWS a.*,b.user_no,b.name as user_name from t_user_auth_audit a inner join t_user b on a.user_id=b.id where a.id=? ';

        let result = await this.executeSqlFirst(sql, [id]);
        if (result) {
            try {
                result.breedCerts = JSON.parse(result.breedCerts);
            } catch (e) {
                result.breedCerts = []
            }
        }
        return result;
    }

    async userAuthAction(){
        let {id} = this.ctx.request.body;
        let action = this.ctx.params.action;
        if(!id || !['repeal','unRepeal'].includes(action)){
            return ResponseUtil.retErr('参数错误');
        }

        let sql = 'select * from t_user_auth_audit where id=?';
        let obj = await this.executeSqlFirst(sql, [id]);
        if (!obj) {
            return ResponseUtil.retErr('未找到该审核信息');
        }

        if(obj.status != 1){
            return ResponseUtil.retErr('只有已审核通过时才能作废');
        }

        let params = {
            id: id,
            valid:action==='repeal'?0:1
        };
        let result = await this.executeUpdate('t_user_auth_audit', params);
        return result.affectedRows;
    }


    async userAuthAudit() {

        let {id, status, auditReason} = this.ctx.request.body;

        if (!id || ![1, 2].includes(status) || (status === 2 && !auditReason)) {
            return ResponseUtil.retArgErr();
        }

        let loginUserInfo = this.ctx.getLoginInfo();
        let operatorType = loginUserInfo.operatorType;
        let operatorId = loginUserInfo.operatorId;
        let createBy = loginUserInfo.createBy;
        let isAdmin = loginUserInfo.isAdmin;

        let sql = 'select * from t_user_auth_audit where id=?';
        let obj = await this.executeSqlFirst(sql, [id]);
        if (!obj) {
            return ResponseUtil.retErr('未找到该审核信息');
        }

        if(obj.valid != 1){
            return ResponseUtil.retErr('该审核信息已作废');
        }

        if (obj.status != 0) {
            return ResponseUtil.retErr('认证信息已审核');
        }

        let params;

        if (status === 1) {
            params = {
                id: id,
                status: status,
                audit_by: createBy,
                audit_by_id: operatorId,
                audit_time: new Date()
            };
        } else {
            params = {
                id: id,
                status: status,
                audit_by: createBy,
                audit_by_id: operatorId,
                audit_time: new Date(),
                audit_reason: auditReason
            };
        }

        let result = await this.executeUpdate('t_user_auth_audit', params);

        let user = await this.ctx.service.user.selectPureByPrimaryKey(obj.userId);
        let openid = user.openid;
        if (!openid) {
            this.ctx.app.logger.error(`userAuthAudit sendGoodsAuditMessage no openid id=${id}`);
        }
        let messageParams = {
            touser: openid,
            status: status == 1 ? '审核通过' : '审核未通过',
            remark: obj.type == 1 ? '繁殖证审核' : '实名认证审核',
            page: '/pagesSub/pages/user-info/user-info'
        };
        if (status === 2) {
            messageParams.remark = messageParams.remark + ` ; 审核未通过，原因：${auditReason}`;
        }
        this.ctx.service.wechat.sendAuthenticationAuditMessage(messageParams);


        let t = obj.type == 1 ? '繁殖证' : '实名认证';
        let c = status == 1 ? '审核通过' : '审核未通过';
        let p = status == 1 ? '恭喜您' : '抱歉您的';
        let notifyParams = {
            category: NotifyConstant.CATEGORY.SYSTEM,
            title: t + '审核',
            content: p + ` ${t} ${c}`,
            from_user_id: DefaultUser.USER_ID,
            to_user_id: obj.userId,
            group_type: 'single'
        };
        if (status === 2) {
            notifyParams.content = notifyParams.content + ` ; 原因：${auditReason}`;
        }
        let insertResult = await this.executeInsert('t_notify', notifyParams);
        let notifyId = insertResult.insertId;

        let toUserParams = {
            notify_id: notifyId,
            to_user_id: obj.userId
        };
        await this.executeInsert('t_notify_touserid', toUserParams);

        return result.affectedRows;
    }


    async saveUserMargin() {
        let {userId, amount, remark} = this.ctx.request.body;
        if (!userId || !this.ctx.positiveInteger(amount) || amount < 1) {
            return ResponseUtil.retArgErr();
        }
        let loginUserInfo = this.ctx.getLoginInfo();
        let operatorId = loginUserInfo.operatorId;
        let createBy = loginUserInfo.createBy;

        let conn = await this.app.mysql.beginTransaction();

        try {

            let sql = 'select * from t_user_margin where user_id=? ';
            let margin = await this.executeSqlFirst(sql, [userId]);
            if (margin) {
                let sql = 'update t_user_margin set amount=amount+?,remark=? where id=?';
                let size = await this.executeSqlSucc(sql, [amount, remark, margin.id]);
                if (size <= 0) {
                    throw Error('添加保证金失败')
                }
            } else {
                let params = {
                    user_id: userId,
                    amount: amount,
                    frozen: 0,
                    remark: remark
                };
                let result = await this.executeInsert('t_user_margin', params);
                if (!result.affectedRows) {
                    throw Error('添加保证金失败')
                }
            }

            let params = {
                user_id: userId,
                amount: amount,
                remark: remark,
                create_by: createBy,
                create_by_id: operatorId
            };

            let result = await this.executeInsert('t_user_margin_record', params);
            if (!result.affectedRows) {
                throw Error('添加保证金记录失败')
            }

            await conn.commit();
            return 1;

        } catch (e) {
            this.ctx.app.logger.error('saveUserMargin error', e.message);
            await conn.rollback();
            throw Error(e.message);
        }

    }


    async updateShopTradeAmount(userId, amount) {
        try {
            let sql = 'select id,trade_amount from t_shop where user_id=? ';
            let shopInfo = await this.executeSqlFirst(sql, [userId]);
            if (shopInfo) {
                sql = 'update t_shop set trade_amount=? where id=?';

                let tradeAmount = shopInfo['tradeAmount'] + amount;
                if (tradeAmount < 0) {
                    tradeAmount = 0;
                }
                await this.executeSqlSucc(sql, [tradeAmount, shopInfo.id]);
            }
            return 1;
        } catch (e) {
            this.ctx.app.logger.error('updateShopTradeAmount error', e.message);
            return 1;
        }
    }


    async selectPureByPrimaryKey(userId) {
        let sql = 'select * from t_user where id=? ';
        let result = await this.executeSqlFirst(sql, [userId]);
        return result;
    }

}

module.exports = UserService;
